package com.gitee.wsl.struct.tree.ext

import com.gitee.wsl.struct.tree.NodeElement
import com.gitee.wsl.struct.tree.TreeElement

/**
 * This function go through tree and counts children. Root element is not counted.
 *
 * @return All child and nested child count.
 */
val <T,E: TreeElement<T, E>> TreeElement<T, E>.nodeCount: Int
    get() {
        if(this !is NodeElement || children.isNullOrEmpty()) return 0
        return children!!.size + children!!.sumOf(TreeElement<T,E>::nodeCount)
    }

/**
 * @return The number of edges on the longest path between current node and a descendant leaf.
 */
val <T,E: TreeElement<T, E>> TreeElement<T, E>.height: Int
    get() {
        if(this !is NodeElement || children.isNullOrEmpty()) return 0
        val childrenMaxDepth = children!!.maxOfOrNull(TreeElement<T,E>::height) ?: -1 // -1 because this method counts nodes, and edges are always one less then
        // nodes.
        return childrenMaxDepth + 1
    }

val <T,E: TreeElement<T, E>> TreeElement<T, E>.leftCount: Int
    get() {
        return if (this.isLeaf) {
             1
        } else if(this is NodeElement<T,E>){
             children?.fold(0, { count, child -> count + child.leftCount})?:0
        } else
            0
    }